﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;
using System.Configuration;
using RedSand.Web.Mvc;
using RedSand.Web.Language;
using System.Reflection;
using System.Text.RegularExpressions;

namespace RedSand.Site.Controllers
{
    [Authorization]
    public class BaseController : Controller
    {
        protected int UserID
        {
            get 
            {
                int id = Convert.ToInt32(Session["CurrentUserID"]);
                if (User.Identity.IsAuthenticated && id == 0)
                {
                    id = RsDataManager.GetInfo<RedSand.Site.Models.UserInfo>("UserGetInfo", new { UserName = User.Identity.Name }).UserID;
                    Session["CurrentUserID"] = id;
                }
                return id;
            }
            set { Session["CurrentUserID"] = value; }
        }
        protected string LanguageCode
        {
            get
            {
                return RsLanguage.LanguageCode;
            }
            set
            {
                RsLanguage.LanguageCode = value;
            }
        }

        public new ActionResult Redirect(string url)
        {
            if (Request.IsAjaxRequest())
            {
                return JavaScript("location='" + url + "'");
            }
            else
            {
                return base.Redirect(url);
            }
        }

        public ActionResult RedirectToLogin()
        {
            return Redirect("/account/login");
        }

        #region message
        protected void AddMessage(string message)
        {
            Session["Message"] += "[msg]" + message;
        }
        protected void AddMessage(Message message)
        {
            Session["Message"] += "[msg]" + RsLanguage.Translate(message.ToString(), "Message");
        }
        protected void AddMessage(string resourceTag, string resourceGroup)
        {
            Session["Message"] += "[msg]" + RsLanguage.Translate(resourceTag, resourceGroup);
        }
        protected ActionResult AjaxMessage(string message)
        {
            return JavaScript("showMessage('" + message + "')");
        }
        protected ActionResult AjaxMessage(string resoureTag, string resourceGroup)
        {
            return JavaScript("showMessage('" + RsLanguage.Translate(resoureTag, resourceGroup) + "')");
        }
        public ActionResult AjaxMessage(Message message)
        {
            return JavaScript("showMessage('" + RsLanguage.Translate(message.ToString(), "Message") + "')");
        }
        protected ActionResult AjaxModelError()
        {
            string msg = "";
            foreach (var value in ModelState.Values)
            {
                foreach (var error in value.Errors)
                {
                    msg += "[msg]" + error.ErrorMessage;
                }
            }
            return JavaScript("showMessage(\"" + HttpUtility.JavaScriptStringEncode(msg) + "\")");
        }
        public MvcHtmlString GetMessage()
        {
            var result = MvcHtmlString.Create((string)Session["Message"]);
            Session.Remove("Message");
            return result;
        }
        #endregion

        #region translate
        protected string Translate(string resourceTag)
        {
            return RsLanguage.Translate(resourceTag);
        }
        protected string Translate(string resourceTag, string resourceGroup)
        {
            return RsLanguage.Translate(resourceTag, resourceGroup);
        }
        #endregion

        #region image
        public string UploadImage()
        {
            try
            {
                if (Request.Files.Count > 0)
                {
                    HttpPostedFileBase fileupload = Request.Files[0];
                    string ext = Path.GetExtension(fileupload.FileName).ToLower();
                    string filefilter = ".jpg|.png|.bmp|.jpeg|.gif";
                    if (!filefilter.Contains(ext))
                    {
                        return "Error: Định dạng file không đúng";
                    }
                    Session["PreviewImage"] = fileupload;
                    return "/Base/ViewImage/" + new Random().Next(100, 999);
                }
                return "Error: Chưa chọn file";
            }
            catch (Exception ex)
            {
                return "Error: " + ex.Message;
            }
        }
        public void ViewImage()
        {
            Response.Clear();
            HttpPostedFileBase file = (HttpPostedFileBase)Session["PreviewImage"];
            if (file == null)
            {
                Response.ContentType = "image/jpeg";
                System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(200, 30);
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);
                System.Drawing.Font f = new System.Drawing.Font("arial", 15);
                g.FillRectangle(System.Drawing.Brushes.White, 0, 0, 200, 30);
                g.DrawString("Ảnh không tồn tại", f, System.Drawing.Brushes.DarkBlue, 0, 0);
                bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            else
            {
                Response.ContentType = file.ContentType;
                int length = file.ContentLength;
                byte[] buffer = new byte[length];
                file.InputStream.Position = 0;
                file.InputStream.Read(buffer, 0, length);
                Response.OutputStream.Write(buffer, 0, length);
            }
            Response.End();
        }
        protected string SaveImage(string oldPath)
        {
            string path = "/Content/Upload/"+GetControllerName().Replace("Controller", "/");

            HttpPostedFileBase file = (HttpPostedFileBase)Session["PreviewImage"];

            if (file != null)
            {
                try
                {
                    if (!Directory.Exists(Request.PhysicalApplicationPath + path))
                    {
                        Directory.CreateDirectory(Request.PhysicalApplicationPath + path);
                    }
                    string filename = path + DateTime.Now.ToString("ddMMyyyymmhhssff") + Path.GetExtension(file.FileName);
                    file.SaveAs(Request.PhysicalApplicationPath + filename);
                    Session.Remove("PreviewImage");
                    DeleteFile(oldPath);
                    return filename;
                }
                catch { }
            }
            return oldPath;
        }

        protected string SaveFile(HttpPostedFileBase file, string path)
        {
            try
            {
                path = '/' + path.TrimEnd('/').TrimStart('/') + "/";
                if (!Directory.Exists(Request.PhysicalApplicationPath + path))
                {
                    Directory.CreateDirectory(Request.PhysicalApplicationPath + path);
                }
                string filename = path + DateTime.Now.ToString("ddMMyyyymmhhssff") + Path.GetExtension(file.FileName);
                file.SaveAs(Request.PhysicalApplicationPath + filename);
                return filename;
            }
            catch 
            {
                return string.Empty;
            }
        }
        protected bool DeleteFile(string path)
        {
            if (string.IsNullOrWhiteSpace(path)) return true;
            try
            {
                FileInfo oldFileInfo = new FileInfo(Request.PhysicalApplicationPath + path);
                if (oldFileInfo.Exists) oldFileInfo.Delete();
                return true;
            }
            catch { }
            return false;
        }
        
        #endregion

        protected string GetControllerName()
        {
            string str = ControllerContext.Controller.ToString();
            return str.Substring(str.LastIndexOf('.') + 1);
        }
        protected string HtmlDecode(string input)
        {
            return HttpUtility.HtmlDecode(HttpUtility.HtmlDecode(input));
        }

        //authorization
        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            Session["IsChildAction"] = filterContext.IsChildAction;
        }


        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            if (!System.Threading.Thread.CurrentThread.CurrentCulture.Name.Contains(LanguageCode))
            {
                var CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(LanguageCode);
                CurrentCulture.DateTimeFormat.ShortDatePattern = Translate("ShortDate", "StringFormat");
                CurrentCulture.DateTimeFormat.ShortTimePattern = Translate("ShortTime", "StringFormat");
                CurrentCulture.DateTimeFormat.LongDatePattern = Translate("LongDate", "StringFormat");
                CurrentCulture.DateTimeFormat.LongTimePattern = Translate("LongTime", "StringFormat");
                CurrentCulture.DateTimeFormat.FullDateTimePattern = Translate("FullDateTime", "StringFormat");
                System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCulture;
                System.Threading.Thread.CurrentThread.CurrentUICulture = CurrentCulture;
            }
            base.Initialize(requestContext);
        }
        protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (filterContext.ActionDescriptor.ActionName.ToLower().IndexOf("gadget") == 0)
            {
                //AllowAccessFromOtherDomain();
            }
        }
        protected void AllowAccessFromOtherDomain()
        {
            Response.AddHeader("Access-Control-Allow-Origin", "*");
        }
    }

    public enum Message
    {
        CreateSuccess,
        CreateError,
        UpdateSuccess,
        UpdateError,
        DeleteSuccess,
        DeleteError,
        AccessDenial,
        PageNotFount,
        DataEmpty,
        ValueEmpty,
        DescriptionEmpty,
        ContentEmpty,
        ImageUrlEmpty,
        FileFormatWrong,
        FileUrlEmpty
    }

    public class AjaxOrChildActionAttribute : ActionMethodSelectorAttribute
    {
        public override Boolean IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
        {
            return (controllerContext.HttpContext.Request.IsAjaxRequest() || controllerContext.IsChildAction);
        }
    }
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class MultiButtonAttribute : ActionNameSelectorAttribute
    {
        public string MatchFormKey { get; set; }
        public string MatchFormValue { get; set; }

        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
        {
            return controllerContext.HttpContext.Request[MatchFormKey] != null &&
                controllerContext.HttpContext.Request[MatchFormKey] == MatchFormValue;
        }
    }
    public class AuthorizationAttribute: AuthorizeAttribute
    {
        private class AllowLink
        {
            public string Link { get; set; }
        }
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (Convert.ToBoolean(httpContext.Session["IsChildAction"])) return true;

            bool loginSuccess = httpContext.User.Identity.IsAuthenticated;

            string action = httpContext.Request.RequestContext.RouteData.Values["action"].ToString().ToLower();
            string controller = httpContext.Request.RequestContext.RouteData.Values["controller"].ToString().ToLower();

            if (controller == "admin" && action == "install") return true;
            if (controller == "account" && action == "login") return true;
            if (controller == "account" && action == "logout") return true;
            if (controller == "home") return true;
            if (controller == "admin" && !loginSuccess) return false;
            if (controller == "action" && httpContext.User.Identity.Name == "admin") return true;

            foreach(var actionItem in RedSand.Site.Models.ActionList.Items)
            {
                Regex reg = new Regex(actionItem.Link);
                if (reg.IsMatch(httpContext.Request.Url.PathAndQuery))
                {
                    if (RsDataManager.ExecuteGetReturn("UserAuthenticate", new { Username = httpContext.User.Identity.Name, Link = actionItem.Link }) == 0)
                    {
                        if (loginSuccess)
                        {
                            string urlRef = (httpContext.Session["UrlReferrer"] ?? "/").ToString();
                            string message = RsLanguage.Translate("AccessDenial", "Message");
                            if (httpContext.Request.IsAjaxRequest())
                            {
                                httpContext.Response.Redirect("/base/ajaxmessage?message=" + Message.AccessDenial, true);
                            }
                            else
                            {
                                httpContext.Session["Message"] = message;
                                httpContext.Response.Redirect(urlRef, true);
                            }
                            return false;
                        }
                        return false;
                    }
                    break;
                }
            }
            if (!httpContext.Request.IsAjaxRequest())
            {
                httpContext.Session["UrlReferrer"] = httpContext.Request.Url;
            }
            return true;
        }
    }
}
